{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "import tkinter\n",
    "from tkinter import messagebox\n",
    "\n",
    "root = tkinter.Tk()\n",
    "\n",
    "# 设置窗口大小和位置\n",
    "root.geometry('300x270+400+100')\n",
    "# 不允许改变窗口大小\n",
    "root.resizable(False, False)\n",
    "# 设置窗口标题\n",
    "root.title('简易计算器-董付国')\n",
    "\n",
    "# 放置用来显示信息的文本框，并设置为只读\n",
    "contentVar = tkinter.StringVar(root, '')\n",
    "contentEntry = tkinter.Entry(root, textvariable=contentVar)\n",
    "contentEntry['state'] = 'readonly'\n",
    "contentEntry.place(x=10, y=10, width=280, height=20)\n",
    "\n",
    "operators = ('+', '-', '*', '/', '**', '//')\n",
    "\n",
    "# 按钮通用代码，参数btn表示按钮的是哪个按钮\n",
    "def buttonClick(btn):\n",
    "    content = contentVar.get()\n",
    "    # 如果已有内容是以小数点开头的，前面加0\n",
    "    if content.startswith('.'):\n",
    "        content = '0' + content\n",
    "    \n",
    "    # 根据不同按钮做出相应的处理\n",
    "    if btn in '0123456789':\n",
    "        content += btn\n",
    "    elif btn == '.':\n",
    "        # 如果最后一个运算数中已经有小数点，就提示错误\n",
    "        lastPart = re.split(r'\\+|-|\\*|/', content)[-1]\n",
    "        if '.' in lastPart:\n",
    "            messagebox.showerror('错误', '小数点太多了')\n",
    "            return\n",
    "        else:\n",
    "            content += btn\n",
    "    elif btn == 'C':\n",
    "        # 清除整个表达式\n",
    "        content = ''\n",
    "    elif btn == '=':\n",
    "        try:\n",
    "            # 对输入的表达式求值\n",
    "            content = str(eval(content))\n",
    "        except Exception as e:\n",
    "            messagebox.showerror('错误', f'表达式错误: {e}')\n",
    "            return\n",
    "    elif btn in operators:\n",
    "        if content.endswith(operators):\n",
    "            messagebox.showerror('错误', '不允许存在连续运算符')\n",
    "            return\n",
    "        content += btn\n",
    "    elif btn == 'Sqrt':\n",
    "        try:\n",
    "            content = str(eval(content) ** 0.5)\n",
    "        except Exception as e:\n",
    "            messagebox.showerror('错误', f'表达式错误: {e}')\n",
    "            return\n",
    "    contentVar.set(content)\n",
    "\n",
    "# 放置清除按钮和等号按钮\n",
    "tkinter.Button(root, text='Clear', command=lambda: buttonClick('C')).place(x=40, y=40, width=80, height=20)\n",
    "tkinter.Button(root, text='=', command=lambda: buttonClick('=')).place(x=170, y=40, width=80, height=20)\n",
    "\n",
    "# 放置10个数字、小数点和计算平方根的按钮\n",
    "digits = list('0123456789.') + ['Sqrt']\n",
    "index = 0\n",
    "for row in range(4):\n",
    "    for col in range(3):\n",
    "        if index < len(digits):\n",
    "            d = digits[index]\n",
    "            index += 1\n",
    "            tkinter.Button(root, text=d, command=lambda x=d: buttonClick(x)).place(x=20 + col * 70, y=80 + row * 50, width=50, height=20)\n",
    "\n",
    "# 放置运算符按钮\n",
    "for index, operator in enumerate(operators):\n",
    "    tkinter.Button(root, text=operator, command=lambda x=operator: buttonClick(x)).place(x=230, y=80 + index * 30, width=50, height=20)\n",
    "\n",
    "root.mainloop()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
